//==============================================================================
//
//  File        : sensor_OV9726.c
//  Description : Firmware Sensor Control File
//  Author      : Philip Lin
//  Revision    : 1.0
//
//=============================================================================

#include "includes_fw.h"
#if defined(DSC_MP3_P_FW)||defined(VIDEO_AMR_R_FW)||defined(VIDEO_AAC_R_FW)||(SENSOR_EN)
#include "config_fw.h"

#if BIND_SENSOR_OV9726

#include "lib_retina.h"
#include "reg_retina.h"

#include "mmp_reg_vif.h"
#include "mmp_reg_scaler.h"
#include "mmp_reg_gpio.h"
#include "mmp_reg_rawproc.h"

#include "mmpf_sensor.h"
#include "mmpf_hif.h"
#include "mmpf_i2cm.h"
#include "mmpf_vif.h"
#include "isp_if.h"
#include "mmpf_usbpccam.h"

#include "mmp_reg_i2cm.h"
#include "mmps_3gprecd.h"
#include "sensor_OV9726.h"
#include "hdm_ctl.h"
#include "mmpf_dram.h"
#include "motor_ctl.h"
#include "flash_ctl.h"
#include "mmpf_pll.h"

#if (CUSTOMER == ASU)
#define DEFAULT_OV9726_FLIP_FOR_W8_APP	(1)
#else
#define DEFAULT_OV9726_FLIP_FOR_W8_APP	(0)
#endif

static MMPF_I2CM_ATTRIBUTE m_snr_I2cmAttribute = {
            SENSOR_I2CM_ID, SENSOR_I2C_ADDR_OV9726, 16, 8, 0, MMP_FALSE, MMP_FALSE, MMP_FALSE,
            MMP_FALSE, 0, 0, 0, MMPF_I2CM_SPEED_HW_250K, NULL, NULL};

#if (CUSTOMER == ASU)&&((SUPPORT_DUAL_DEVICE==1)||(SUPPORT_SWITCH_CAMERA==1))
#if MODEL == 0
	#undef SENSOR_IF 
	#define SENSOR_IF                (SENSOR_IF_MIPI_1_LANE)
#else
	#undef SENSOR_IF 
	#define SENSOR_IF                (SENSOR_IF_PARALLEL)
#endif
#define SENSOR_ID_OV9726 1
#endif

#ifndef SENSOR_ID_OV9726
#define SENSOR_ID_OV9726 0
#endif

#if(CUSTOMER == PNS)
MMP_UBYTE SEN_EN=0;
#endif
MMP_USHORT gsEnableTestPattern=0;

static	MMP_UBYTE   vif_id = 0;

#define G2_CLK                      (120)

extern MMP_USHORT  gsSensorPreviewWidth[], gsSensorPreviewHeight[];
extern MMP_USHORT  gsCurPreviewMode, gsCurPhaseCount;
//extern MMP_USHORT  gsSensorMode;
extern MMP_USHORT  m_usVideoQuality;
extern MMP_USHORT	m_gsISPCoreID;

extern MMPS_3GPRECD_VIDEO_FORMAT m_VideoFmt;
extern MMP_BOOL    gbAutoFocus;

extern MMP_USHORT m_usResolType;
extern MMP_ULONG   glPccamResolution;
extern H264_FORMAT_TYPE gbCurH264Type;

#if (IQ_TABLE_LOAD_FROM_FLASH == 0)
//#if ((CUSTOMER == ASU) && (TOTAL_SENSOR_NUMBER == 1)) || (CUSTOMER != ASU)
const __align(4) ISP_UINT8 Sensor_IQ_CompressedText[] = {
    #if CUSTOMER == PNS || CUSTOMER == IPC
        #include "isp_8451_iq_data_v2_OV9726_PNS.xls.ciq.txt"
    #else
        #include "isp_8451_iq_data_v2_OV9726_ASU.xls.ciq.txt"
    #endif
//#include "isp_8451_iq_data_v2_OV9726.xls.ciq.txt"//same as ov9710, not tune yet
};
//#endif
#endif

#define  SENSOR_ROTATE_180    0   

#define  PIXEL_RATE_60M      (1)
#define  PIXEL_RATE_42M      (2)

#define VOLTAGE33V 0
#define VOLTAGE28V 1
#define VOLTAGE18V 2

#define SENSOR_VOLTAGE      VOLTAGE18V
//#if (G1_CLK < 120000)
    #define  SENSOR_PIXEL_RATE          (PIXEL_RATE_42M)
//#else
//    #define  SENSOR_PIXEL_RATE          (PIXEL_RATE_60M)
//#endif

//#define SUPPORT_AUTO_FOCUS 0

//#include "sensor_ctl.h"
//#include "preview_ctl.h"
//#include "XDATAmap.h"
//#include "3A_ctl.h"
//#include "OV9726.h"
//#include "motor_ctl.h"

#define BASE_SHUTTER_50HZ		251
#define BASE_SHUTTER_60HZ		209

void SNR_OV9726_SetSensorResolution_Customer(ISP_SENSOR_RESOL res);
void SNR_OV9726_InitSensor_Customer(void);
#if SUPPORT_AUTO_FOCUS
void MOTOR_OV9726_VCM_InitMotor_Customer(void);
void MOTOR_OV9726_VCM_SetAFPosition_Customer(MMP_USHORT af_pos);
#endif

static VENUS_SYSTEM_MODE gSystemMode;

//------------------------------------------------------------------------------
//  Function    : OV9726_Sensor_PreviewMode
//  Description :
//------------------------------------------------------------------------------
extern MMP_BYTE gbSignalType;
extern MMPF_SENSOR_FUNCTION *gsSensorFunction ;

static void OV9726_Sensor_PreviewMode(MMP_USHORT usPreviewmode)
{
	gsCurPreviewMode = usPreviewmode;
	//gsCurPhaseCount = usPhasecount;

	switch (usPreviewmode) {
	case 0:
		RTNA_DBG_Str(3, "Sensor 5M (1920x1080) preview mode\r\n");
		//ISP_IF_3A_Control(ISP_3A_DISABLE); //patrick@100518
	    gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_FALSE);

		gSystemMode = VENUS_SYSTEM_MODE_SNAPSHOT;//ISP_IF_SNR_SetBeforeCapture();
		ISP_IF_IQ_SetSysMode(0); //Steven NOTE:please reference excel define: 0=capture, 1=preview, 2=video....
		SNR_OV9726_SetSensorResolution_Customer(ISP_SENSOR_RESOL_1920x1080);

        //set color transform 16 ~ 235
        MMPF_Scaler_SetOutputColor(MMPF_SCALER_PATH_0, MMP_TRUE, MMPF_SCALER_COLRMTX_BT601); //MMPF_SCALER_COLRMTX_FULLRANGE

		ISP_IF_AE_SetFPS(0);
		//ISP_IF_3A_Control(ISP_3A_ENABLE); //patrick@100518
	    gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_TRUE);
		break;

	case 1:
		RTNA_DBG_Str(0, "Sensor preview (1280x720) mode\r\n");
			RTNA_DBG_Str(0, "SENSOR_VIDEO_MODE\r\n");
			//ISP_IF_3A_Control(ISP_3A_DISABLE); //patrick@100518
    	    gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_FALSE);

			gSystemMode = VENUS_SYSTEM_MODE_PREVIEW;//ISP_IF_SNR_SetBeforePreview();
			ISP_IF_IQ_SetSysMode(1); //Steven NOTE:please reference excel define: 0=capture, 1=preview, 2=video....
			SNR_OV9726_SetSensorResolution_Customer(ISP_SENSOR_RESOL_1280x720);

#if 0	
	        MMPF_VIF_GetVIFGrabResolution(&ulWidth, &ulHeight);
                dbg_printf(3, "[2] ulWidth = %d, ulHeight = %d\r\n", ulWidth, ulHeight); 
#endif

                //set color transform 16 ~ 235
                MMPF_Scaler_SetOutputColor(MMPF_SCALER_PATH_0, MMP_TRUE, MMPF_SCALER_COLRMTX_BT601); //YUV or H264 run BT601 , MPEG run FULLRANGE

				ISP_IF_AE_SetFPS(0);
  			//ISP_IF_3A_Control(ISP_3A_ENABLE);
    	    gsSensorFunction->MMPF_Sensor_Set3AStatus(MMP_TRUE);
		break;
	}
}
extern void GPIO_OutputControl(MMP_UBYTE num, MMP_UBYTE status);
extern volatile MMP_UBYTE   gbDramID;
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Initialize
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_Initialize_OV9726(void)
{
	//AITPS_PAD   pPAD  = AITC_BASE_PAD;
	AITPS_VIF   pVIF = AITC_BASE_VIF;

    RES_TYPE_CFG *cur_res;
    
	RTNA_DBG_Str(0, "MMPF_Sensor_Initialize_OV9726...Begin\r\n");

    //Init globol variable used by DSC
    gsSensorPreviewWidth[0] = 1280;
    gsSensorPreviewHeight[0] = 720;
    // use 1.3M for preview, check sensor preview setting
    gsSensorPreviewWidth[1] = 1280;
    gsSensorPreviewHeight[1] = 720;

    #if 0
	pPAD->PAD_PSCK = PAD_E8_CURRENT | PAD_E4_CURRENT | PAD_PULL_HIGH;
	pPAD->PAD_PSDA = PAD_E4_CURRENT | PAD_PULL_HIGH;
	pPAD->PAD_PSEN = PAD_E4_CURRENT | PAD_PULL_HIGH;
	#endif

	#if (CUSTOMER == LGT) || (CUSTOMER == CCN) || (CUSTOMER == SNO)  || (CUSTOMER == CPL)
    GPIO_OutputControl(CAM_EN, TRUE);
	MMPF_OS_Sleep_MS(5);
    #endif
    #if (CUSTOMER == ASU) && defined(CAM_PWR_EN) //real_board
        GPIO_OutputControl(CAM_EN_1M, MMP_TRUE);
        GPIO_OutputControl(CAM_PWR_EN, TRUE);
        MMPF_OS_Sleep_MS(5);

        //must be MMPF_DRAMID_WINBOND_SDR16
        //MMPF_OS_Sleep_MS(5);
        GPIO_OutputControl(CAM_EN_1M, MMP_FALSE);
    #else
    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_TRUE);
    	MMPF_OS_Sleep_MS(5);
        GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_FALSE);
    }
    else{
	    MMPF_VIF_SetPIODir(VIF_SIF_SEN, MMP_TRUE);
	    MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_TRUE);  //Pin output high
    	MMPF_OS_Sleep_MS(5);
    	MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_FALSE);//Pin output low
    }
	#endif
	#if (CUSTOMER == PNS)
    	GPIO_OutputControl(SEN_POW, TRUE);
    	SEN_EN = 1;
    #endif
	
	MMPF_OS_Sleep_MS(5);

	pVIF->VIF_SENSR_CLK_CTL[vif_id] = VIF_SENSR_CLK_EN;
	MMPF_OS_Sleep_MS(5);

	/*Reset Sensor 500mS*/
	MMPF_VIF_SetPIODir(VIF_SIF_RST, MMP_TRUE);

	MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_FALSE);
	MMPF_OS_Sleep_MS(5);

	MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_TRUE);
	MMPF_OS_Sleep_MS(5);
	#if 1// debug for checking I2C access
	{
	MMP_USHORT chipid, tmpdata;
	gsSensorFunction->MMPF_Sensor_GetReg(0x00, &tmpdata);
	chipid = tmpdata<<8;
	gsSensorFunction->MMPF_Sensor_GetReg(0x01, &tmpdata);
	chipid |= (tmpdata & 0xFF);
	if(chipid!=0xFFFF)
	{
	    RTNA_DBG_Str(0, "Chip ID:");
	    RTNA_DBG_Short(0, chipid);
	    RTNA_DBG_Str(0, "\r\n");
	}else
	{
	    RTNA_DBG_Str(0, "Chip ID Read error! Check sensor and I2C\r\n");
	}
	}
	#endif

	SNR_OV9726_InitSensor_Customer();

    cur_res = GetResCfg(glPccamResolution);
    if(cur_res->res_w > gsSensorPreviewWidth[1] || cur_res->res_h > gsSensorPreviewHeight[1]) {
        gsSensorFunction->MMPF_Sensor_SetPreviewMode(0);
    }
    else{
        gsSensorFunction->MMPF_Sensor_SetPreviewMode(1);
    }

#if SUPPORT_AUTO_FOCUS
	MOTOR_OV9726_VCM_InitMotor_Customer();
#endif

#if SUPPORT_FLASH_LIGHT
	VR_Flash_Init();
#endif

	RTNA_DBG_Str(0, "MMPF_Sensor_Initialize_OV9726...End\r\n");
	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_PowerDown_OV9726
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR  MMPF_Sensor_PowerDown_OV9726(void)
{
	AITPS_VIF  pVIF = AITC_BASE_VIF;
	#if (CUSTOMER == PNS) && SUPPORT_UAC
	AITPS_GPIO	pGPIO = AITC_BASE_GPIO;
	AITPS_GBL   pGBL = AITC_BASE_GBL;
	#endif

	
	gsSensorFunction->MMPF_Sensor_SetReg(0x0100,0);
	MMPF_OS_Sleep_MS(33);
	
	MMPF_VIF_EnableInputInterface(MMP_FALSE);

    //MMPF_VIF_SetPIODir(VIF_SIF_RST, MMP_TRUE);
	//MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_TRUE);  //Pin output high
	//MMPF_OS_Sleep_MS(10);
	MMPF_VIF_SetPIOOutput(VIF_SIF_RST, MMP_FALSE);//Pin output low
	MMPF_OS_Sleep_MS(10);

	#if ((CUSTOMER == ASU) && defined(CAM_PWR_EN)) || (CUSTOMER == PNS) //real_board
	#else
    if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        GPIO_OutputControl(GPIO_SENSOR_PSEN, MMP_TRUE);
    }
    else{
	    MMPF_VIF_SetPIODir(VIF_SIF_SEN, MMP_TRUE);
	    MMPF_VIF_SetPIOOutput(VIF_SIF_SEN, MMP_TRUE);  //Pin output high
	}
	MMPF_OS_Sleep_MS(5);
	#endif

	pVIF->VIF_SENSR_CLK_CTL[vif_id] &= (~ VIF_SENSR_CLK_EN) ;   //output sensor main clock

	#if (CUSTOMER == LGT) || (CUSTOMER == CCN) || (CUSTOMER == SNO) || (CUSTOMER == CPL) 
    GPIO_OutputControl(CAM_EN, FALSE);
	MMPF_OS_Sleep_MS(10);
    #endif
    
    #if (CUSTOMER == PNS) && SUPPORT_UAC
    SEN_EN = 0;
	if(((pGPIO->GPIO_DATA[0]&0x100000)>>TI_RES)==0){
		GPIO_OutputControl(SEN_POW, FALSE);
		pGBL->GBL_IO_CTL1 &= ~(GBL_I2C_0_PAD_EN);
	}
    #endif

	MMPF_OS_Sleep_MS(20);

	RTNA_DBG_Str3( "MMPF_Sensor_PowerDown_OV9726() \r\n");
	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetFrameRate_OV9726
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_SetFrameRate_OV9726(MMP_UBYTE ubFrameRate)
{
	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetPreviewMode
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR MMPF_Sensor_SetPreviewMode_OV9726(MMP_USHORT usPreviewmode)
{
	OV9726_Sensor_PreviewMode(usPreviewmode);

	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetPreviewMode
//  Description :
//------------------------------------------------------------------------------

static MMP_ERR MMPF_Sensor_ChangePreviewMode_OV9726(
						MMP_USHORT usCurPreviewmode, MMP_USHORT usCurPhasecount,
						MMP_USHORT usNewPreviewmode, MMP_USHORT usNewPhasecount)
{
	OV9726_Sensor_PreviewMode(usNewPreviewmode);

	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_ChangeMode
//  Description :
//------------------------------------------------------------------------------

/*static*/ MMP_ERR MMPF_Sensor_ChangeMode_OV9726(MMP_USHORT usPreviewmode, MMP_USHORT usCapturemode)
{
	switch (usPreviewmode) {
	case 0:
		switch (usCapturemode) {
		case 0:
			break;
		case 1:
			break;
		}
		break;
	case 1:
		switch (usCapturemode) {
		case 0:// SXGA preview, 5M capture
			MMPF_Sensor_SetPreviewMode_OV9726(0);
			// wait 3 frame ...
		   // MMPF_Sensor_WaitFrame(5);
			break;
		case 1:
			MMPF_Sensor_SetPreviewMode_OV9726(1);
			// wait 3 frame ...
			//MMPF_Sensor_WaitFrame(3);

			break;
		}
		break;
	}

	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_InitializeVIF
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_InitializeVIF_OV9726(void)
{
	AITPS_MIPI  pMIPI = AITC_BASE_MIPI;
	AITPS_VIF  pVIF = AITC_BASE_VIF;
	//MMP_UBYTE   vif_id = 0;
	ISP_HDM_VIF_IF vif_if;
	MMP_ULONG   ulSENSORCLK;
	MMP_UBYTE div;

	// register sensor (functions and variables)
	//ISP_IF_SNR_Register();
	RTNA_DBG_Str(0, "ISP_IF_SNR_Register...E\r\n");

    #if SUPPORT_AUTO_FOCUS
	#if (CUSTOMER == NMG)  
    GPIO_OutputControl(AF_EN, TRUE);
    #endif
	#if (CUSTOMER == LGT)  
    //GPIO_OutputControl(AF_EN, FALSE);
    #endif
	#if (CUSTOMER == CCN)  
    //GPIO_OutputControl(AF_EN, FALSE);
    #endif
	MMPF_OS_Sleep_MS(20);
    #endif

#if SUPPORT_AUTO_FOCUS
	// register motor
//	ISP_IF_MOTOR_Register();
#endif

    #if (SENSOR_IF == SENSOR_IF_PARALLEL)
	MMPF_VIF_RegisterInputInterface(MMPF_VIF_PARALLEL);
	pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR | VIF_VSYNC_POLAR_NEG;
    #else
    #if 0
	pMIPI->MIPI_DATA1_SOT = 0x10; // From KW
	pMIPI->MIPI_DATA2_SOT = 0x10; // From KW
	pMIPI->MIPI_DATA3_SOT = 0x10; // From KW
	pMIPI->MIPI_DATA4_SOT = 0x10; // From KW
	#endif
	
	pMIPI->MIPI_DATA0_DLY[vif_id] = 0x1000;  // set SOT counter to 0x10
	pMIPI->MIPI_DATA1_DLY[vif_id] = 0x1000;  // set SOT counter to 0x10
	
	//#if (CUSTOMER == NMG)  
    //pMIPI->MIPI_CLK_DEL = 0x05;  // MIPI clock lane delay selection [3:0]
    //pMIPI->MIPI_CLK_CFG |= 0x02;  // MIPI clock lane delay
    //#endif
	MMPF_VIF_RegisterInputInterface(MMPF_VIF_MIPI);
    #endif

	// initialize VIF OPRs
#if (SENSOR_IF == SENSOR_IF_PARALLEL)
	vif_if = ISP_HDM_VIF_IF_PARALLEL;		//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_PARALLEL, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_1_LANE)	
	vif_if = ISP_HDM_VIF_IF_MIPI_SINGLE_0;	//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_SINGLE_0, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_2_LANE)		
	vif_if = ISP_HDM_VIF_IF_MIPI_DUAL_01;	//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_DUAL_01, 22);
#elif (SENSOR_IF == SENSOR_IF_MIPI_4_LANE)		
	vif_if = ISP_HDM_VIF_IF_MIPI_QUAD;		//ISP_HDM_IF_InitVIF(ISP_HDM_VIF_IF_MIPI_QUAD, 22);
#endif	

	{
		pVIF->VIF_INT_HOST_EN[vif_id] = 0;
		pVIF->VIF_INT_CPU_SR[vif_id] = VIF_INT_ALL;
		pVIF->VIF_OUT_EN[vif_id] = 0;
		//pVIF->VIF_DEFT_EN = 0;
		pVIF->VIF_RAW_OUT_EN[vif_id] = 0;
		pVIF->VIF_FRME_SKIP_NO[vif_id] = 0;
		pVIF->VIF_FRME_SKIP_EN[vif_id] = 0;

		//RTNA_DBG_Str(0,"InitializeVIF\r\n");
		MMPF_PLL_GetGroupFreq(4, &ulSENSORCLK);

#if 1
		if (ulSENSORCLK % 24000) {
            div = VIF_SENSR_CLK_PLL_D12;
		} else {
            div = (ulSENSORCLK / 24000) - 1;//make this to 24MHz
		}
#else
		switch(ulSENSORCLK){
			case 96000:
			    div = VIF_SENSR_CLK_PLL_D4;//24MHz
				break;
			case 144000:
                div = VIF_SENSR_CLK_PLL_D6;//24MHz
				break;
			case 192000:
                div = VIF_SENSR_CLK_PLL_D8;//24MHz
				break;
			case 216000:
                div = VIF_SENSR_CLK_PLL_D9;//24MHz
				break;
			case 240000:
                div = VIF_SENSR_CLK_PLL_D10;//24MHz
				break;
			case 120000:
                div = VIF_SENSR_CLK_PLL_D5;//24MHz
				break;
			default:
                div = VIF_SENSR_CLK_PLL_D12;
				//pVIF->VIF_SENSR_CLK_FREQ[vif_id] = VIF_SENSR_CLK_PLL_D12;  // 144/12 = 12M
				break;
		}
#endif
		pVIF->VIF_SENSR_CLK_FREQ[vif_id] = div;
		dbg_printf(1, "%dKHz div %d\r\n", ulSENSORCLK, div + 1);

		#if (SENSOR_IF==SENSOR_IF_PARALLEL)
		pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR | VIF_VSYNC_POLAR_NEG;		
		#elif (CUSTOMER == PNS)
		pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR | VIF_VSYNC_POLAR_NEG;
        #elif (CUSTOMER == ASU) && (MODEL >= 1)
		pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR;
        #else
		pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_PIXL_ID_POLAR | VIF_VSYNC_POLAR_NEG;//| VIF_12BPP_OUT_EN;
		//pVIF->VIF_SENSR_CTL[vif_id] = VIF_SENSR_LATCH_PST | VIF_LINE_ID_POLAR | VIF_VSYNC_POLAR_NEG;
        #endif	

		pVIF->VIF_YUV_CTL[vif_id] = VIF_YUV_FORMAT_VUY;
/*
        if (vif_id == 0) {
    		pVIF->VIF_0_SENSR_SIF_EN = VIF_SIF_SEN | VIF_SIF_RST;
    		pVIF->VIF_0_SENSR_SIF_DATA = VIF_SIF_RST;
		}
		else {
    		pVIF->VIF_1_SENSR_SIF_EN = VIF_SIF_SEN | VIF_SIF_RST;
    		pVIF->VIF_1_SENSR_SIF_DATA = VIF_SIF_RST;
		}
*/
		pVIF->VIF_SENSR_CLK_CTL[vif_id] = VIF_SENSR_CLK_EN;
		pVIF->VIF_OPR_UPD[vif_id] = VIF_OPR_UPD_EN | VIF_OPR_UPD_FRAME;

		if (vif_if==ISP_HDM_VIF_IF_PARALLEL) {
			RTNA_DBG_Str0("ISP_HDM_VIF_IF_PARALLEL\r\n");
		}
		else {
		#if (CUSTOMER == PNS) && (MODEL == 1)
		    pMIPI->MIPI_DATA0_CFG[vif_id] = ((pMIPI->MIPI_DATA0_CFG[vif_id] & ~MIPI_DAT_SRC_SEL_MASK) | MIPI_DAT_SRC_PHY_2) | MIPI_CSI2_EN;
		#else
			pMIPI->MIPI_DATA0_CFG[vif_id] = ((pMIPI->MIPI_DATA0_CFG[vif_id] & ~MIPI_DAT_SRC_SEL_MASK) | MIPI_DAT_SRC_PHY_1) | MIPI_CSI2_EN;
		#endif
		    if (vif_if == ISP_HDM_VIF_IF_MIPI_DUAL_01) {
			    pMIPI->MIPI_DATA1_CFG[vif_id] = ((pMIPI->MIPI_DATA1_CFG[vif_id] & ~MIPI_DAT_SRC_SEL_MASK) | MIPI_DAT_SRC_PHY_2) | MIPI_CSI2_EN;
			}
			#if (CHIP == P_V2)
			else if(vif_if==ISP_HDM_VIF_IF_MIPI_QUAD){
			    pMIPI->MIPI_DATA2_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_2;
			    pMIPI->MIPI_DATA3_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_3;
			    pMIPI->MIPI_DATA4_CFG = MIPI_CSI2_EN | MIPI_SRC_SEL_4;
			}
			#endif
		}
	}


	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_InitializeISP
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_InitializeISP_OV9726(void)
{
	// register sensor (functions and variables)
	RTNA_DBG_Str(0, "ISP_IF_LIB_Init...\r\n");
	// check if ISP Lib and IQ are mismatched.
	ISP_IF_LIB_Init();
	// check if ISP Lib and IQ are mismatched.
	if (ISP_IF_LIB_CompareIQVer() != MMP_ERR_NONE) {
		RTNA_DBG_Str(0, "Wrong ISP lib version!\r\n");
	    return MMP_ERR_NONE;
	}

	//RTNA_DBG_Str(0, "ISP_IF_3A_Init...S\r\n");
	// initialize 3A
	ISP_IF_3A_Init();

	// set AF type (ISP_AF_TYPE_ONE_SHOT / ISP_AF_TYPE_CONTINUOUS)
	ISP_IF_AF_SetType(ISP_AF_TYPE_CONTINUOUS);
	//RTNA_DBG_Str(0, "ISP_IF_3A_Init...E\r\n");

	ISP_IF_AE_SetLowLuxMode(0);//disable Low light Compensation

	return  MMP_ERR_NONE;
}

//============================================================================

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_SetAFPosition_OV9726
//  Description :
// ---------------------------------------
static MMP_ERR MMPF_Sensor_SetAFPosition_OV9726(MMP_UBYTE ubPos)
{
#if SUPPORT_AUTO_FOCUS
	//if (gISPConfig.AutoFocusMode == VENUS_AF_MODE_MANUAL) {
		//gAFConfig.AFPos = ubPos;
		ISP_IF_AF_SetPos(ubPos, 8);
		MOTOR_OV9726_VCM_SetAFPosition_Customer(ISP_IF_AF_GetPos(0));
	//}

            //RTNA_DBG_Str(3, "  ubPos = ");       
            //RTNA_DBG_Short(3, ubPos);
            //RTNA_DBG_Str(3, "\r\n");
#endif
	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Do3AOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAWBOperation_OV9726(void)
{
if(!gsEnableTestPattern)
{
//	ISP_IF_R_DoAWB();
	ISP_IF_AWB_Execute();
	ISP_IF_CALI_Execute();
	ISP_IF_IQ_SetAWBGains(ISP_IF_AWB_GetGainR(), ISP_IF_AWB_GetGainG(), ISP_IF_AWB_GetGainB());
}
	return  MMP_ERR_NONE;
}

//ISP_UINT32 gISPFrameCnt;
#define MinFrameDivsor 5 // Gason@20120111, by OV suggestion, under 15 fps, dummy line will work every 5 frame.
#if (CUSTOMER == ASU)
static ISP_UINT32 frame_div = 3;
#else
static ISP_UINT32 frame_div = 5;
#endif
static ISP_UINT32 gISPFrameCnt = 0;

ISP_UINT32 s_gain_9726; //For Color patch infor
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAEOperation_ST
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAEOperation_ST_OV9726(void)
{
if(!gsEnableTestPattern)
{
	static ISP_UINT32 again, dgain, shutter, vsync;


    if(ISP_IF_3A_GetSwitch(ISP_3A_ALGO_AE) != 1) return MMP_ERR_NONE;

#if (CUSTOMER == ASU)
	if (ISP_IF_AE_GetLightCond() <= 48)
		frame_div = 3;
	else 
		frame_div = 3; 
#else
	if (ISP_IF_AE_GetLightCond() <= 48)
		frame_div = 3;
	else 
		frame_div = 5; 
#endif
		
//	switch (frame_cnt++ % 6) {
	switch (gISPFrameCnt % frame_div) {
	case 0:
		ISP_IF_AE_Execute();
		{
			ISP_UINT32 H, L;
			ISP_UINT32 new_vsync   = ISP_IF_AE_GetVsync();	
			ISP_UINT32 new_shutter = ISP_IF_AE_GetShutter();
			
			again = ISP_IF_AE_GetAGain();
			dgain = ISP_IF_AE_GetDGain();

			//if fix 15fps, set vsnyc & shutter to 1/15s.
			if (ISP_IF_AE_GetBaseShutter() == BASE_SHUTTER_50HZ) {
				vsync   = VR_MAX(new_vsync, new_shutter + 5);
				shutter = VR_MIN(VR_MAX(new_shutter, 1), vsync - 5);

				//if (new_shutter >= 6*ISP_IF_AE_GetBaseShutter())
				//	vsync = 6*ISP_IF_AE_GetBaseShutter() + 5;
			}
			else {

				if (ISP_IF_AE_GetFPS() == 15) {
					again   = VR_MAX(ISP_IF_AE_GetShutter() * again / (8 * ISP_IF_AE_GetBaseShutter()), ISP_IF_AE_GetAGainBase());
					shutter = 8 * ISP_IF_AE_GetBaseShutter();
					vsync   = shutter + 5;
				}
				else {
					vsync   = VR_MAX(new_vsync, new_shutter + 5);
					shutter = VR_MIN(VR_MAX(new_shutter, 1), vsync - 5);
				}
			}

			//calc sensor gain
			s_gain_9726 = again * dgain / ISP_IF_AE_GetDGainBase();
			
			if (s_gain_9726 >= ISP_IF_AE_GetAGainBase() * 16) {
				dgain 	= s_gain_9726 * ISP_IF_AE_GetDGainBase() / 16;
				s_gain_9726  = ISP_IF_AE_GetAGainBase() * 16;
			} else {
				dgain 	= ISP_IF_AE_GetDGainBase();
			}
			
			if (s_gain_9726 >= ISP_IF_AE_GetAGainBase() * 8) {
				H = 7;
			} else if (s_gain_9726 >= ISP_IF_AE_GetAGainBase() * 4) {
				H = 3;
			} else if (s_gain_9726 >= ISP_IF_AE_GetAGainBase() * 2) {
				H = 1;
			} else {
				H = 0;
			}
			
			L = s_gain_9726 * 16 / ISP_IF_AE_GetAGainBase() / (H+1) - 16;
			
			if (L > 15) L = 15;
			gsSensorFunction->MMPF_Sensor_SetReg(0x0104, 1); // Gason@20120111,by OV suggestion, group hold for sync shutter & gain
			
			gsSensorFunction->MMPF_Sensor_SetReg(0x0340, (ISP_UINT16) (vsync >> 8));
			gsSensorFunction->MMPF_Sensor_SetReg(0x0341, (ISP_UINT16)vsync);
			gsSensorFunction->MMPF_Sensor_SetReg(0x0202, (ISP_UINT16)(shutter >> 8));
			gsSensorFunction->MMPF_Sensor_SetReg(0x0203, (ISP_UINT16)shutter);				
			gsSensorFunction->MMPF_Sensor_SetReg(0x0205, (H<<4)+L);

			gsSensorFunction->MMPF_Sensor_SetReg(0x0104, 0);// Gason@20120111, by OV suggestion, group release for sync shutter & gain
		}
		break;
	}
}
	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAEOperation_END
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAEOperation_END_OV9726(void)
{
if(!gsEnableTestPattern)
{
    if(ISP_IF_3A_GetSwitch(ISP_3A_ALGO_AE) != 1) return MMP_ERR_NONE;

	switch (gISPFrameCnt++ % frame_div) {
	case 1:
		#if (CUSTOMER == ASU)
		ISP_IF_IQ_SetAEGain(ISP_IF_AE_GetDGainBase());
		#else
		ISP_IF_IQ_SetAEGain(0x2A0);
		#endif
		break;
	case 2:
		ISP_IF_AE_GetHWAcc(1);
		break;
	}
}
	return  MMP_ERR_NONE;
}


//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAFOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAFOperation_OV9726(void)
{
#if SUPPORT_AUTO_FOCUS
	if(gbAutoFocus == MMP_TRUE){
		//VR_AF_GetAcc();
		ISP_IF_AF_GetHWAcc(1);
		//ISP_IF_R_DoAF();
	}
#endif

	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoAFOperation
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_Sensor_DoAFOperation_FrameStart_OV9726(void)
{
#if SUPPORT_AUTO_FOCUS
	if(gbAutoFocus == MMP_TRUE){
		//VR_AF_GetAcc();
		//ISP_IF_R_GetAFAcc();
		//ISP_IF_R_DoAF();
		{
			static ISP_UINT32 frame_cnt = 0;

			switch (frame_cnt++ % 1) {
			case 0:
				ISP_IF_AF_Execute();
				MOTOR_OV9726_VCM_SetAFPosition_Customer(ISP_IF_AF_GetPos(0));
				break;
			}
		}
	}
#endif

	return  MMP_ERR_NONE;
}

//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_DoIQOperation_OV9726
//  Description :
//------------------------------------------------------------------------------
//extern MMP_UBYTE gbSkypeMode;

static MMP_ERR  MMPF_Sensor_DoIQOperation_OV9726(void)
{
	// switch IQ table if video format is H264
	//PCAM_USB_VIDEO_FORMAT vidFmt = pcam_get_info()->pCamVideoFormat;
	
	//if (vidFmt == PCAM_USB_VIDEO_FORMAT_H264)	ISP_IF_F_SetVideoMode(1);
	//else										ISP_IF_F_SetVideoMode(0);

 
	// set IQ at frame end to ensure frame sync	
	ISP_IF_IQ_SetAll();
#if SUPPORT_ISP_ENGINEERING_MODE_FUNCTION
	{
	extern MMP_USHORT PCAM_UpdateGAMMAtoRAM(void);
	PCAM_UpdateGAMMAtoRAM();
	}
#endif
	ISP_IF_IQ_CheckBypass();
#if (CUSTOMER == ASU)
	{ ///PATCH FOR COLOR NOISE ( satrution , BLC )
		ISP_UINT32 tempREG1;	
	
		tempREG1 = ISP_IF_IQ_GetOpr(0x70f6,1);	
		ISP_IF_IQ_SetOpr(0x70f6,1,tempREG1 - (s_gain_9726/ISP_IF_AE_GetAGainBase()/3));	
		
		tempREG1 = ISP_IF_IQ_GetOpr(0x70f9,1);
		ISP_IF_IQ_SetOpr(0x70f9,1,tempREG1 - (s_gain_9726/ISP_IF_AE_GetAGainBase()/3));

/*		if(s_gain_9726>8*ISP_IF_AE_GetAGainBase())
		{
			tempREG1 = ISP_IF_IQ_GetOpr(0x7021,1);
			ISP_IF_IQ_SetOpr(0x7021,1,tempREG1 + (s_gain_9726/ISP_IF_AE_GetAGainBase()/4));
			tempREG1 = ISP_IF_IQ_GetOpr(0x7022,1);
			ISP_IF_IQ_SetOpr(0x7022,1,tempREG1 + (s_gain_9726/ISP_IF_AE_GetAGainBase()/4));	
			tempREG1 = ISP_IF_IQ_GetOpr(0x7023,1);
			ISP_IF_IQ_SetOpr(0x7023,1,tempREG1 + (s_gain_9726/ISP_IF_AE_GetAGainBase()/4));	
			tempREG1 = ISP_IF_IQ_GetOpr(0x7024,1);
			ISP_IF_IQ_SetOpr(0x7024,1,tempREG1 + (s_gain_9726/ISP_IF_AE_GetAGainBase()/4));
		}		
*/
	}///PATCH
#endif
	//RTNA_DBG_Str(0, "DoIQOperation_OV9726()\r\n");
	
	return  MMP_ERR_NONE;
}

// Steven ADD
//------------------------------------------------------------------------------
//  Function    : MMPF_SetLightFreq
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR  MMPF_SetLightFreq_OV9726(MMP_USHORT usMode)
{
#if 0

	RTNA_DBG_Str(0, "MMPF_SetLightFreq_OV9726 : ");
	RTNA_DBG_Short(0, usMode);
	RTNA_DBG_Str(0, "\r\n");

	/*
	typedef enum {
		VENUS_FLICKER_MODE_OFF              = 0,
		VENUS_FLICKER_MODE_AUTO             = 1,
		VENUS_FLICKER_MODE_60HZ             = 2,
		VENUS_FLICKER_MODE_50HZ             = 3,
		VENUS_FLICKER_MODE_CAL_BASESHUTTER  = 4
	} VENUS_FLICKER_MODE;
	*/

	switch(usMode) {
	case 0:
	case 2:
		//gISPConfig.FlickerMode = VENUS_FLICKER_MODE_60HZ;
		ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_60HZ);
		break;
	case 1:
	case 3:
		//gISPConfig.FlickerMode = VENUS_FLICKER_MODE_50HZ;
		ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_50HZ);
		break;
	default:
		//gISPConfig.FlickerMode = VENUS_FLICKER_MODE_AUTO;
		ISP_IF_AE_SetFlicker(ISP_AE_FLICKER_AUTO);
	}
#endif

	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_SetStableState_OV9726(MMP_BOOL bStableState)
{
	return  MMP_ERR_NONE;
}

MMP_ERR MMPF_SetHistEQState_OV9726(MMP_BOOL bHistEQState)
{

	return  MMP_ERR_NONE;
}

extern volatile MMP_UBYTE gbDramID;
static MMP_ERR  MMPF_Sensor_SetReg_OV9726(MMP_USHORT usAddr, MMP_USHORT usData)
{
	if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_0;  // for AIT8433 70 pin package
    }
    else{
        m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_1;  // for AIT8451 105 pin package
    }
	MMPF_I2cm_WriteReg(&m_snr_I2cmAttribute, usAddr, usData);
	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_GetReg_OV9726(MMP_USHORT usAddr, MMP_USHORT *usData)
{
	*usData = 0xFF;
	if((gbDramID == MMPF_DRAMID_WINBOND_SDR16) || (gbDramID == MMPF_DRAMID_WINBOND_SDR16_1_8V)){
        m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_0;  // for AIT8433 70 pin package
    }
    else{
        m_snr_I2cmAttribute.uI2cmID = MMPF_I2CM_ID_1;  // for AIT8451 105 pin package
    }
    MMPF_I2cm_ReadReg(&m_snr_I2cmAttribute, usAddr, usData);
	
	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetImageScene_OV9726(MMP_USHORT imgSceneID)
{
#if 0
/*
typedef enum {
	ISP_SCENE_AUTO					= 0,	// scene mode
	ISP_SCENE_PORTRAIT				= 1,	// scene mode
	ISP_SCENE_LANDSCAPE				= 2,	// scene mode
	ISP_SCENE_SPORTS				= 3,	// scene mode
	ISP_SCENE_SUNSET				= 4,	// scene mode
	ISP_SCENE_DUSK					= 5,	// scene mode
	ISP_SCENE_DAWN					= 6,	// scene mode
	ISP_SCENE_NIGHT_SHOT			= 7,	// scene mode
	ISP_SCENE_AGAINST_LIGHT			= 8,	// scene mode
	ISP_SCENE_TEXT					= 9,	// scene mode
	ISP_SCENE_MANUAL				= 10,	// scene mode
	ISP_SCENE_INDOOR				= 11,	// scene mode
	ISP_SCENE_SNOW					= 12,	// scene mode
	ISP_SCENE_FALL					= 13,	// scene mode
	ISP_SCENE_WAVE					= 14,	// scene mode
	ISP_SCENE_FIREWORKS				= 15,	// scene mode
	ISP_SCENE_SHOW_WIN				= 16,	// scene mode
	ISP_SCENE_CANDLE				= 17,	// scene mode
	ISP_SCENE_NONE					= 18	// camera mode
} ISP_SCENE;
*/
	imgSceneID = (imgSceneID % (ISP_SCENE_NONE+1));

	RTNA_DBG_Str(3, "MMPF_SetImageScene_OV9726 : ");
	RTNA_DBG_Byte(3, imgSceneID);
	RTNA_DBG_Str(3, "\r\n");

	//if (g3AConfig.Control3A == ISP_3A_ENABLE)
		MMPF_Sensor_CheckFrameEnd(1);
	ISP_IF_F_SetScene(imgSceneID);
#endif

	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAEMode_OV9726(MMP_UBYTE ubAEMode, MMP_UBYTE ubISOMode)
{
#if 0
/*
typedef enum {
	AE_MODE_AUTO						= 0,
	AE_MODE_MANUAL						= 1,
	AE_MODE_ISO							= 2,
	AE_MODE_SHUTTER						= 3
} VENUS_AE_MODE;
*/
/*
typedef enum {
	AE_ISO_AUTO					= 0,
	AE_ISO_50					= 1,
	AE_ISO_100					= 2,
	AE_ISO_200					= 3,
	AE_ISO_400					= 4,
	AE_ISO_800					= 5,
	AE_ISO_1600					= 6,
	AE_ISO_3200					= 7,
	ISP_AE_ISO_NUM
} VENUS_AE_ISO;
*/
    #if 0 //FIXME, VSN_V2
	if (ubAEMode == 3)
		ISP_IF_AE_SetISO(ISP_AE_MODE_AUTO);
	else
	#endif
		ISP_IF_AE_SetISO(ubISOMode);
#endif
	
	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAFMode_OV9726(MMP_UBYTE ubAFMode)
{
#if 0
/*
typedef enum {
	VENUS_AF_MODE_AUTO					= 0,
	VENUS_AF_MODE_MANUAL				= 1,
	VENUS_AF_MODE_MACRO					= 2,
	VENUS_AF_MODE_FULL					= 3,
	VENUS_AF_MODE_MOTOR_TEST            = 4,
	VENUS_AF_MODE_NULL					= 5
} VENUS_AF_MODE;
*/
	RTNA_DBG_Str(3, "MMPF_Sensor_SetAFMode_OV9726 : ");
	RTNA_DBG_Byte(3, ubAFMode);
	RTNA_DBG_Str(3, "\r\n");

	//gISPConfig.AutoFocusMode = (MMP_UBYTE)ubAFMode;
	//if (g3AConfig.Control3A == ISP_3A_ENABLE)
	//	MMPF_Sensor_CheckFrameEnd(1);
	ISP_IF_AF_SetMode(ubAFMode);
#endif

	return  MMP_ERR_NONE;
}

//======================================================================//
// function : MMPF_Sensor_SetImageEffect                                //
// parameters:                                                          //
// return :                                                             //
// description :                                                        //
//======================================================================//
static MMP_ERR  MMPF_Sensor_SetImageEffect_OV9726(MMP_USHORT imgEffectID)
{
#if 0
/*
typedef enum {
	ISP_IMAGE_EFFECT_NORMAL			= 0,
	ISP_IMAGE_EFFECT_GREY			= 1,
	ISP_IMAGE_EFFECT_SEPIA			= 2,
	ISP_IMAGE_EFFECT_NEGATIVE		= 3,
	ISP_IMAGE_EFFECT_ANTIQUE		= 4,
	ISP_IMAGE_EFFECT_WATERCOLOR		= 5,
	ISP_IMAGE_EFFECT_PORTRAIT		= 6,
	ISP_IMAGE_EFFECT_LANDSCAPE		= 7,
	ISP_IMAGE_EFFECT_SUNSET			= 8,
	ISP_IMAGE_EFFECT_DUSK			= 9,
	ISP_IMAGE_EFFECT_DAWN			= 10,
	ISP_IMAGE_EFFECT_RED			= 11,
	ISP_IMAGE_EFFECT_GREEN			= 12,
	ISP_IMAGE_EFFECT_BLUE			= 13,
	ISP_IMAGE_EFFECT_YELLOW			= 15,
	ISP_IMAGE_EFFECT_EMBOSS			= 17,
	ISP_IMAGE_EFFECT_OIL			= 18,
	ISP_IMAGE_EFFECT_BW				= 19,
	ISP_IMAGE_EFFECT_SKETCH			= 20,
	ISP_IMAGE_EFFECT_CRAYONE		= 21,
	ISP_IMAGE_EFFECT_WHITEBOARD		= 22,
	ISP_IMAGE_EFFECT_BLACKBOARD		= 23,
	ISP_IMAGE_EFFECT_VIVID			= 24,
	ISP_IMAGE_EFFECT_NUM
} ISP_IMAGE_EFFECT;
*/

	imgEffectID = (imgEffectID % (ISP_IMAGE_EFFECT_NUM+1));

	RTNA_DBG_Str(3, "MMPF_Sensor_SetImageEffect_OV9726 : ");
	RTNA_DBG_Byte(3, imgEffectID);
	RTNA_DBG_Str(3, "\r\n");

	//gISPConfig.ImageEffect = (MMP_USHORT)imgEffectID;
	//if (g3AConfig.Control3A == ISP_3A_ENABLE)
	//	MMPF_Sensor_CheckFrameEnd(1);
	ISP_IF_F_SetImageEffect(imgEffectID);
#endif

	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetAWBType_OV9726(MMP_UBYTE ubType)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetAWBType_OV9726 : ");
	RTNA_DBG_Byte(3, ubType);
	RTNA_DBG_Str(3, "\r\n");

	cAWBtype = ubType;
#endif
	return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetContrast_OV9726(MMP_SHORT ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_Contrast_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

	//gISPConfig.ContrastLevel = ubLevel;
	ISP_IF_F_SetContrast(ubLevel);
#endif

	return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetSaturation_OV9726(MMP_SHORT ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetSaturation_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

	//gISPConfig.SaturationLevel = ubLevel;
	ISP_IF_F_SetSaturation(ubLevel);
#endif

	return  MMP_ERR_NONE;
}
static MMP_ERR  MMPF_Sensor_SetSharpness_OV9726(MMP_SHORT ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetSharpness_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

	//gISPConfig.SharpnessLevel = ubLevel;
	ISP_IF_F_SetSharpness(ubLevel);
#endif

	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetHue_OV9726(MMP_SHORT ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetHue_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

	ISP_IF_F_SetHue(ubLevel);
#endif

	return  MMP_ERR_NONE;
}

static MMP_ERR  MMPF_Sensor_SetGamma_OV9726(MMP_SHORT ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetGamma_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

	ISP_IF_F_SetGamma(ubLevel);
#endif

	return  MMP_ERR_NONE;
}

/*static MMP_ERR  MMPF_Sensor_SetBacklight_OV9726(MMP_UBYTE ubLevel)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetBacklight_OV9726 : ");
	RTNA_DBG_Byte(3, ubLevel);
	RTNA_DBG_Str(3, "\r\n");

//	ISP_IF_F_SetBacklight(ubLevel);
	if(ubLevel > 1){
		ISP_IF_F_SetWDR(ISP_WDR_DISABLE);
	}
	else{
		ISP_IF_F_SetWDR(ISP_WDR_ENABLE);
	}
#endif

	return  MMP_ERR_NONE;
}

*/

static void  MMPF_Sensor_SetCaptureISPSetting_OV9726(MMP_UBYTE usCaptureBegin)
{
#if 0
	AITPS_VIF   pVIF = AITC_BASE_VIF;
	MMP_ULONG   ulVIF_Width, ulVIF_Height;
	//MMP_UBYTE   vif_id = 0;

	/* ToDo: setting IOS and ISP windows*/
	if(MMP_TRUE == usCaptureBegin){
		ulVIF_Width = (pVIF->VIF_GRAB[vif_id].PIXL_ED - pVIF->VIF_GRAB[vif_id].PIXL_ST + 1);
		ulVIF_Height = (pVIF->VIF_GRAB[vif_id].LINE_ED - pVIF->VIF_GRAB[vif_id].LINE_ST + 1);
		//gSensorFunc.SetISPWindows(ulVIF_Width,ulVIF_Height);
	}
#endif
	
	return;
}

/*Prepare for raw preview zoom*/
static void  MMPF_Sensor_SetISPWindow_OV9726(MMP_ULONG ulWidth, MMP_ULONG ulHeight)
{
	//gSensorFunc.SetISPWindows(ulWidth,ulHeight);
	return;
}

/*Check AIT can preview in this resolution*/
static MMP_UBYTE  MMPF_Sensor_CheckPreviewAbility_OV9726(MMP_USHORT usPreviewmode)
{
#if 0
	switch(usPreviewmode){
		case 0:                 //5M can't preview
			return MMP_TRUE;
			break;
		case 1:                 //1.3M can preview
			return MMP_TRUE;
			break;
	}
#endif
	
	return MMP_TRUE;            //5M and 1.3M always can preview
}

static void SetAFWin_OV9726(MMP_USHORT usIndex, MMP_USHORT usPreviewWidth, MMP_USHORT usPreviewHeight,
					MMP_USHORT  usStartX, MMP_USHORT  usStartY, MMP_USHORT  usWidth, MMP_USHORT  usHeight)
{

	//DBG_S3("SetAFWin (TODO)\r\n");
}

//static MMP_BOOL VGAPreview = MMP_TRUE;
static void SetAFEnable_OV9726(MMP_UBYTE enable)
{
//    if (enable) {
		//RTNA_DBG_Str(3, "VENUS_ISP_AUTO_FOCUS_STATUS_START\r\n");
		ISP_IF_AF_Control(ISP_AF_START);
		//actually calling SNR_OV9726_SetAutoFocusControl()
//    } else {
//        RTNA_DBG_Str(3, "VENUS_ISP_AUTO_FOCUS_STATUS_STOP\r\n");
//        ISP_IF_AF_Control(ISP_AF_STOP);
//    }
}

static MMP_ERR MMPF_Sensor_SetAEEnable_OV9726(MMP_UBYTE bEnable)
{
	/*
	if (bEnable) {
		g3AConfig.AE_Enabled     = ON;
	}
	else {
		g3AConfig.AE_Enabled     = OFF;
	}*/

	ISP_IF_3A_SetSwitch(ISP_3A_ALGO_AE, bEnable);

	return MMP_ERR_NONE;
}

static MMP_ERR MMPF_Sensor_SetAWBEnable_OV9726(MMP_UBYTE bEnable)
{
#if 0
	if (bEnable) {
		g3AConfig.AWB_Enabled    = ON;
		g3AConfig.AWBRGB_Enabled = ON;
	}
	else {
		g3AConfig.AWB_Enabled    = OFF;
		g3AConfig.AWBRGB_Enabled = OFF;
	}
#endif

	if(bEnable)
		ISP_IF_AWB_SetMode(ISP_AWB_MODE_AUTO);
	else
		ISP_IF_AWB_SetMode(ISP_AWB_MODE_MANUAL);

	return MMP_ERR_NONE;
}
static void SetAEsmooth_OV9726(MMP_UBYTE smooth)  {return;}
static MMP_ERR MMPF_Sensor_SetExposureValue_OV9726(MMP_UBYTE ev)
{
#if 0
	RTNA_DBG_Str(3, "MMPF_Sensor_SetExposureValue_OV9726 : ");
	//RTNA_DBG_Byte(3, gISPConfig.EV);
	//RTNA_DBG_Str(3, " : ");
	RTNA_DBG_Byte(3, ev);
	RTNA_DBG_Str(3, "\r\n");

	ISP_IF_AE_SetEV(ev);
#endif

	return MMP_ERR_NONE;
}

static MMP_UBYTE GetAFPosition_OV9726     (void){ return 0;/*volatile MMP_UBYTE *GPIO_BASE_B = (volatile MMP_UBYTE *)0x80009400;  return GPIO_BASE_B[0xB0];*/}


static MMP_UBYTE GetAFEnable_OV9726(void)
{
	//return 0;
	return ISP_IF_AF_GetResult();
}

static MMP_UBYTE GetExposureValue_OV9726  (void){return ISP_IF_AE_GetEV();}
static MMP_UBYTE GetAEsmooth_OV9726       (void){return 0;}
//------------------------------------------------------------------------------
//  Function    : MMPF_Sensor_Set3AStatus
//  Description :
//------------------------------------------------------------------------------
static MMP_ERR	MMPF_Sensor_Set3AStatus_OV9726(MMP_BOOL bEnable)
{
	#if 1
	MMPF_Sensor_3A_SetInterrupt(bEnable);
	//#else
	if (bEnable)
		ISP_IF_3A_Control(ISP_3A_ENABLE);
	else
		ISP_IF_3A_Control(ISP_3A_DISABLE);
	#endif
	return	MMP_ERR_NONE;
}

static void  MMPF_Sensor_SetColorID_OV9726(MMPF_SENSOR_ROTATE_TYPE RotateType)
{
	switch(RotateType) {
#if DEFAULT_OV9726_FLIP_FOR_W8_APP
	case MMPF_SENSOR_ROTATE_NO_ROTATE:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x02);
		ISP_IF_IQ_SetColorID(2);
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_90:
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_180:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x01);
		ISP_IF_IQ_SetColorID(3);
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_270:
		break;
	case MMPF_SENSOR_ROTATE_H_MIRROR:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x03);
		ISP_IF_IQ_SetColorID(3);
		break;
	case MMPF_SENSOR_ROTATE_V_FLIP:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x00);
		ISP_IF_IQ_SetColorID(2);
		break;
#else
	case MMPF_SENSOR_ROTATE_NO_ROTATE:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x00);
		ISP_IF_IQ_SetColorID(0);
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_90:
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_180:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x03);
		ISP_IF_IQ_SetColorID(0);
		break;
	case MMPF_SENSOR_ROTATE_RIGHT_270:
		break;
	case MMPF_SENSOR_ROTATE_H_MIRROR:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x01);
		ISP_IF_IQ_SetColorID(0);
		break;
	case MMPF_SENSOR_ROTATE_V_FLIP:
		gsSensorFunction->MMPF_Sensor_SetReg(0x101, 0x02);
		ISP_IF_IQ_SetColorID(0);
		break;
#endif
	}

	ISP_IF_IQ_SetDirection((ISP_UINT8)RotateType);
	return;
}

const ISP_UINT8 get_OV9726_gain_Customer[128] = 
{
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,
	0x00,

	0x00, //0x10
	0x01,
	0x02,
	0x03,
	0x04,
	0x05,
	0x06,
	0x07,
	0x08,
	0x09,
	0x0a,
	0x0b,
	0x0c,
	0x0d,
	0x0e,
	0x0f,


	0x11,//0x20
	0x11,
	0x12,
	0x12,
	0x13,
	0x13,
	0x14,
	0x14,
	0x15,
	0x15,
	0x16,
	0x16,
	0x17,
	0x17,
	0x18,
	0x18,


	0x19,//0x30
	0x19,
	0x1a,
	0x1a,
	0x1b,
	0x1b,
	0x1c,
	0x1c,
	0x1d,
	0x1d,
	0x1e,
	0x1e,
	0x1f,
	0x1f,
	0x31,
	0x31,

	0x31,//0x40
	0x31,
	0x31,
	0x31,
	0x32,
	0x32,
	0x32,
	0x32,
	0x33,
	0x33,
	0x33,
	0x33,
	0x34,
	0x34,
	0x34,
	0x34,

	0x35,//0x50
	0x35,
	0x35,
	0x35,
	0x36,
	0x36,
	0x36,
	0x36,
	0x37,
	0x37,
	0x37,
	0x37,
	0x38,
	0x38,
	0x38,
	0x38,

	0x39,//0x60
	0x39,
	0x39,
	0x39,
	0x3a,
	0x3a,
	0x3a,
	0x3a,
	0x3b,
	0x3b,
	0x3b,
	0x3b,
	0x3c,
	0x3c,
	0x3c,
	0x3c,

	0x3d,//0x70
	0x3d,
	0x3d,
	0x3d,
	0x3e,
	0x3e,
	0x3e,
	0x3e,
	0x3f,
	0x3f,
	0x3f,
	0x3f,
	0x71,
	0x71,
	0x71,
	0x71,
};

static void MMPF_Sensor_SetSensorGain_OV9726(MMP_ULONG gain)
{
	MMP_USHORT s_gain;
	MMP_ULONG sensor_gain;
	
	//return;//T.B.D
	s_gain = VR_MIN(16 * VR_MAX(gain, ISP_IF_AE_GetAGainBase()) / ISP_IF_AE_GetAGainBase() , 127);
	sensor_gain = get_OV9726_gain_Customer[s_gain];
	gsSensorFunction->MMPF_Sensor_SetReg(0x0205, sensor_gain & 0xff);
}

static void MMPF_Sensor_SetSensorShutter_OV9726(MMP_ULONG shutter, MMP_ULONG vsync)
{
		MMP_ULONG new_vsync =  VR_MAX(vsync, shutter + 5);  //+8
		MMP_ULONG new_shutter = VR_MIN(VR_MAX(shutter, 1), new_vsync - 2);
	//	MMP_ULONG ExtraVsyncWidth;

        //return;//T.B.D
		gsSensorFunction->MMPF_Sensor_SetReg(0x0340, new_vsync >> 8);
		gsSensorFunction->MMPF_Sensor_SetReg(0x0341, new_vsync);

		gsSensorFunction->MMPF_Sensor_SetReg(0x0202, new_shutter >> 8);
		gsSensorFunction->MMPF_Sensor_SetReg(0x0203, new_shutter);
}

MMPF_SENSOR_FUNCTION  SensorFunction_OV9726 =
{
	MMPF_Sensor_Initialize_OV9726,
	MMPF_Sensor_InitializeVIF_OV9726,
	MMPF_Sensor_InitializeISP_OV9726,
	MMPF_Sensor_PowerDown_OV9726,
	MMPF_Sensor_SetFrameRate_OV9726,
	MMPF_Sensor_ChangeMode_OV9726,
	MMPF_Sensor_ChangePreviewMode_OV9726,
	MMPF_Sensor_SetPreviewMode_OV9726,
	MMPF_Sensor_SetReg_OV9726,
	MMPF_Sensor_GetReg_OV9726,
	MMPF_Sensor_DoAWBOperation_OV9726,
	MMPF_Sensor_DoAEOperation_ST_OV9726,
	MMPF_Sensor_DoAEOperation_END_OV9726,
	MMPF_Sensor_DoAFOperation_OV9726,
	MMPF_Sensor_DoAFOperation_FrameStart_OV9726,
	MMPF_Sensor_DoIQOperation_OV9726,
	MMPF_Sensor_SetImageEffect_OV9726,
	MMPF_SetLightFreq_OV9726,
	MMPF_SetStableState_OV9726,
	MMPF_SetHistEQState_OV9726,
	MMPF_Sensor_SetAFPosition_OV9726,
	SetAFWin_OV9726,
	SetAFEnable_OV9726,
	MMPF_Sensor_SetAEEnable_OV9726,
	MMPF_Sensor_SetAWBEnable_OV9726,
	MMPF_Sensor_SetExposureValue_OV9726,
	SetAEsmooth_OV9726,
	MMPF_Sensor_SetImageScene_OV9726,
	GetAFPosition_OV9726,
	GetAFEnable_OV9726,
	GetExposureValue_OV9726,
	GetAEsmooth_OV9726,
	MMPF_Sensor_SetAWBType_OV9726,
	MMPF_Sensor_SetContrast_OV9726,
	MMPF_Sensor_SetSaturation_OV9726,
	MMPF_Sensor_SetSharpness_OV9726,
	MMPF_Sensor_SetHue_OV9726,
	MMPF_Sensor_SetGamma_OV9726,
 //   MMPF_Sensor_SetBacklight_OV9726,
	MMPF_Sensor_SetAEMode_OV9726,
	MMPF_Sensor_SetAFMode_OV9726,
	MMPF_Sensor_SetCaptureISPSetting_OV9726,
	MMPF_Sensor_SetISPWindow_OV9726,
	MMPF_Sensor_CheckPreviewAbility_OV9726,
	MMPF_Sensor_Set3AStatus_OV9726,
	MMPF_Sensor_SetColorID_OV9726,
	MMPF_Sensor_SetSensorGain_OV9726,
	MMPF_Sensor_SetSensorShutter_OV9726
};
/*
MMPF_SENSOR_FUNCTION  SensorFunction_dummy =
{
0,0
};
*/
MMP_USHORT SNR_OV9726_Reg_Init_Customer[] = {

		// @@ WXGA_RAW_30FPS MIPI 1280x720 (720P)

		0x0103, 0x01,
		//0x3021, 0x20,  // [5]: 0: use internal 1.5V LDO(default), 1: use external 1.5V LDO 
		0x3026, 0x00,
		0x3027, 0x00,
		0x3002, 0xe8,
		0x3004, 0x03,
		0x3005, 0xff,
		
		0x3703, 0x42,  // reserved
		0x3704, 0x10,  // reserved
		0x3705, 0x45,  // reserved
		0x3603, 0xaa,  // reserved
		0x3632, 0x2f,  // reserved
		0x3620, 0x66,  // reserved
		0x3621, 0xc0,  // reserved
		
//        0x0340, 0x03,  // frame_length_lines[15:8]
//        0x0341, 0x48,  // frame_length_lines[7:0]
//        0x0342, 0x06,  // line_length_pck[15:8]
//        0x0343, 0x80,  // line_length_pck[7:0]
//        0x0202, 0x03,
//        0x0203, 0x43,
		
		0x3833, 0x04,  // reserved
		0x3835, 0x02,  // reserved
		0x4702, 0x04,  // reserved
		0x4704, 0x01,  // bossino @ 20120822, for solving AE line missing issue in parallel sensor
		0x4706, 0x08,
		0x5052, 0x01,  // reserved
		0x3819, 0x6e,  // reserved
		0x3817, 0x94,  // reserved
		0x3a18, 0x00,  // AEC gain ceiling
		0x3a19, 0x7f,  // AEC gain ceiling
		0x404e, 0x7e,  // reserved
#if SENSOR_VOLTAGE == VOLTAGE33V
		0x3631, 0x70,  // reserved
		0x3633, 0x90,  // reserved
#endif
#if (SENSOR_VOLTAGE == VOLTAGE28V) || (SENSOR_VOLTAGE == VOLTAGE18V)
		0x3631, 0x52,  // reserved
		0x3633, 0x50,  // reserved
#endif
		0x3630, 0xd2,  // reserved
		0x3604, 0x08,  // reserved
		0x3601, 0x40,  // reserved
		0x3602, 0x14,  // reserved
		0x3610, 0xa0,  // reserved
		0x3612, 0x20,  // reserved
		
		0x034c, 0x05,  // 1296
		0x034d, 0x10,
		0x034e, 0x03,  // 808
		0x034f, 0x28,
//		0x0347, 0x28,
		 
		
#if (G2_CLK == 120)
#if (SENSOR_PIXEL_RATE == PIXEL_RATE_60M)  // for 60M pixel/sec
		0x0340, 0x03,  // frame_length_lines[15:8]
		0x0341, 0x48,  // frame_length_lines[7:0]
		
		0x0342, 0x07,  // line_length_pck[15:8]  // for input clock = 24MHz @ 30fps
		0x0343, 0x72,  // line_length_pck[7:0]
#endif		
#if (SENSOR_PIXEL_RATE == PIXEL_RATE_42M)  // for 42M pixel/sec
		0x0340, 0x03,  // frame_length_lines[15:8]
		0x0341, 0x48,  // frame_length_lines[7:0]
		
		0x0342, 0x06,  // line_length_pck[15:8]  // for input clock = 24MHz @ 30fps
		0x0343, 0x80,  // line_length_pck[7:0]
#endif
#endif
#if (G2_CLK == 132)
		0x0340, 0x03,  // frame_length_lines[15:8]
		0x0341, 0x48,  // frame_length_lines[7:0]
		0x0342, 0x06,  // line_length_pck[15:8]  // for input clock = 22MHz @ 30fps
		0x0343, 0xD4,  // line_length_pck[7:0]
#endif
		
		0x0202, 0x03,
		0x0203, 0x43,
		
		0x0301, 0x0A,  // vt_pix_clk_div
		0x0303, 0x01,  // vt_sys_clk_div

#if (SENSOR_IF != SENSOR_IF_PARALLEL)
		0x3002, 0x00,
		0x3004, 0x00,
		0x3005, 0x00,
		
		0x4801, 0x0f,
		0x4803, 0x05,
		0x4601, 0x16,

		0x3014, 0x05,  // [2]: MIPI enable
#endif
#if (SENSOR_PIXEL_RATE == PIXEL_RATE_60M)  // 60M pixels/sec
		0x3104, 0x80,  // use two PLLs, PLL1 and PLL2
#endif
#if (SENSOR_PIXEL_RATE == PIXEL_RATE_42M)  // 42M pixels/sec	
		0x3104, 0x20,  // use single PLL
#endif
		// tomy@2010_05_18, reduce MIPI high speed prepare period
		0x4827, 0x03, // hs_prepare_min, default = 0x32
		0x4802, 0x80, // [7]: hs_prepare_sel

#if (SENSOR_PIXEL_RATE == PIXEL_RATE_60M)  // 60M pixels/sec
		0x0305, 0x04,
		0x0307, 0x64, //0x64, // change 60M/sec to 42M/sec
		0x300c, 0x02,  // reserved
		0x300d, 0x20,  // reserved
#endif		
#if (SENSOR_PIXEL_RATE == PIXEL_RATE_42M)  // 42M pixels/sec	
		0x0305, 0x04,
		0x0307, 0x46, //0x64, // change 60M/sec to 42M/sec
		0x300c, 0x02,  // reserved
		0x300d, 0x1c,  // reserved
#endif
		0x300e, 0x01,  // reserved
		0x3010, 0x01,  // reserved
#if (SENSOR_IF != SENSOR_IF_PARALLEL)
		0x460e, 0x81,  // [7]: MIPI mode 2 enable
#endif
#if DEFAULT_OV9726_FLIP_FOR_W8_APP
		0x0101, 0x02,  // [0]: mirror on/off, [1]: flip on/off
#else
		0x0101, 0x00,  // [0]: mirror on/off, [1]: flip on/off
#endif
		
		0x3707, 0x14,  // reserved
		0x3622, 0x9f,  // reserved
		0x3400, 0x05,
		// Sensor function disable
		0x3a00, 0x08,  // night mode off
		0x5047, 0x63,  // [0]: BLC enable, [1]: AWB gain enable, [5]: LENC bias plus
		0x4002, 0x45,  // [6]: BLC auto enable
		0x5000, 0x02,  // [1]: WPC enable, [2]: BPC enable, [7]: LENC correction enable
		0x5001, 0x00,  // [0]: AWB enable

		0x3406, 0x01,  // AWB disable
		0x3503, 0x13,  // AGC/AEC disable
		0x4005, 0x18,  // [4]: output black line enable
		0x0100, 0x01,  // streaming
		
#if (SENSOR_IF != SENSOR_IF_PARALLEL)
#else 

		0x3a0f, 0x64,
		0x3a10, 0x54,
		0x3a11, 0xc2,
		0x3a1b, 0x64,
		0x3a1e, 0x54,
		0x3a1a, 0x05,
		0x0345, 0x01,
#endif
};

void SNR_OV9726_InitSensor_Customer(void) {
	// implement your initialize sensor routine here ==============================================

	ISP_UINT32 i;

	//MMPF_Sensor_ConfigI2C( SENSOR_I2C_ADDR_OV9726, ISP_I2C_TYPE_2A1D);

	//ISP_HDM_IF_EnableSensor(ISP_HDM_SNR_ENABLE_HIGH);

	// set register...........
	RTNA_DBG_Str(0, "set sensor reg\r\n");
	for (i = 0; i < sizeof(SNR_OV9726_Reg_Init_Customer)/4; i++) {
		gsSensorFunction->MMPF_Sensor_SetReg(SNR_OV9726_Reg_Init_Customer[i*2], SNR_OV9726_Reg_Init_Customer[i*2+1]);
		MMPF_OS_Sleep_MS(3);
	}

    if (gsEnableTestPattern) {  //set H.264 test pattern
        gsSensorFunction->MMPF_Sensor_SetReg(0x0601,4);	//0:no pattern 1:solid color 2:color bars 3:fade to gray color bars 4:PN9
        gsEnableTestPattern = 0;
    }

	MMPF_OS_Sleep_MS(20);
	ISP_IF_AE_SetBaseShutter( BASE_SHUTTER_50HZ, BASE_SHUTTER_60HZ);
	ISP_IF_AE_SetMinFPSx10(75);
	// Set preview resolution as default
	//SNR_OV9726_SetSensorResolution_Customer(ISP_SENSOR_RESOL_1280x720);//Bug fix, must call ISP_IF_IQ_SetSysMode first
}

void SNR_OV9726_SetSensorAddMode_Customer(ISP_UINT8 enable)
{

}
#if 0
MMP_USHORT SNR_OV9726_Reg_1280x720_Customer[] = 
{
		// @@ WXGA_RAW_30FPS MIPI 1280x720 (720P)

		0x0103, 0x01,
		0x3026, 0x00,
		0x3027, 0x00,
		0x3002, 0xe8,
		0x3004, 0x03,
		0x3005, 0xff,
		
		0x3703, 0x42,  // reserved
		0x3704, 0x10,  // reserved
		0x3705, 0x45,  // reserved
		0x3603, 0xaa,  // reserved
		0x3632, 0x2f,  // reserved
		0x3620, 0x66,  // reserved
		0x3621, 0xc0,  // reserved
		
//        0x0340, 0x03,  // frame_length_lines[15:8]
//        0x0341, 0x48,  // frame_length_lines[7:0]
//        0x0342, 0x06,  // line_length_pck[15:8]
//        0x0343, 0x80,  // line_length_pck[7:0]
//        0x0202, 0x03,
//        0x0203, 0x43,
		
		0x3833, 0x04,  // reserved
		0x3835, 0x02,  // reserved
		0x4702, 0x04,  // reserved
		0x4704, 0x00,
		0x4706, 0x08,
		0x5052, 0x01,  // reserved
		0x3819, 0x6e,  // reserved
		0x3817, 0x94,  // reserved
		0x3a18, 0x00,  // AEC gain ceiling
		0x3a19, 0x7f,  // AEC gain ceiling
		0x404e, 0x7e,  // reserved
		0x3631, 0x70,  // reserved
		0x3633, 0x90,  // reserved
		0x3630, 0xd2,  // reserved
		0x3604, 0x08,  // reserved
		0x3601, 0x40,  // reserved
		0x3602, 0x14,  // reserved
		0x3610, 0xa0,  // reserved
		0x3612, 0x20,  // reserved

#if 0
		0x034c, 0x05,  // 1296
		0x034d, 0x10,
		0x034e, 0x02,  // 736
		0x034f, 0xe0,
		0x0347, 0x28,
#else
		0x034c, 0x05,  // 1296
		0x034d, 0x10,
		0x034e, 0x03,  // 808
		0x034f, 0x28,
		//0x0347, 0x28,

#endif
		 
		0x0340, 0x03,  // frame_length_lines[15:8]
		0x0341, 0x48,  // frame_length_lines[7:0]
		
#if 1//(G2_CLK == 144)
		0x0342, 0x07,  // line_length_pck[15:8]  // for input clock = 24MHz @ 30fps
		0x0343, 0x72,  // line_length_pck[7:0]
#endif
#if 0//(G2_CLK == 132)
		0x0342, 0x06,  // line_length_pck[15:8]  // for input clock = 22MHz @ 30fps
		0x0343, 0xD4,  // line_length_pck[7:0]
#endif
//        0x0342, 0x05,  // line_length_pck[15:8]  // for input clock = 18MHz @ 30fps
//        0x0343, 0x96,  // line_length_pck[7:0]
		
		0x0202, 0x03,
		0x0203, 0x43,
		
		0x0301, 0x0A,  // vt_pix_clk_div
		0x0303, 0x01,  // vt_sys_clk_div

		0x3002, 0x00,
		0x3004, 0x00,
		0x3005, 0x00,
		
		0x4801, 0x0f,
		0x4803, 0x05,
		0x4601, 0x16,
		0x3014, 0x05,  // [2]: MIPI enable
		0x3104, 0x80,  // reserved

		// tomy@2010_05_18, reduce MIPI high speed prepare period
		0x4827, 0x03, // hs_prepare_min, default = 0x32
		0x4802, 0x80, // [7]: hs_prepare_sel
		
		0x0305, 0x04,
		0x0307, 0x64,
		
		0x300c, 0x02,  // reserved
		0x300d, 0x20,  // reserved
		0x300e, 0x01,  // reserved
		0x3010, 0x01,  // reserved
		0x460e, 0x81,  // [7]: MIPI mode 2 enable
#if DEFAULT_OV9726_FLIP_FOR_W8_APP
		0x0101, 0x02,  // [0]: mirror on/off, [1]: flip on/off
#else
		0x0101, 0x00,  // [0]: mirror on/off, [1]: flip on/off
#endif
		
		0x3707, 0x14,  // reserved
		0x3622, 0x9f,  // reserved

#if 0
		0x0601, 0x02,  // test pattern
#endif


		// Sensor function disable
		0x3a00, 0x08,//0x78,  // night mode off
		0x5047, 0x63,  // [0]: BLC enable, [1]: AWB gain enable, [5]: LENC bias plus
		0x4002, 0x45,  // [6]: BLC auto enable
		0x5000, 0x06,  // [1]: WPC enable, [2]: BPC enable, [7]: LENC correction enable
		0x5001, 0x00,  // [0]: AWB enable
		0x3406, 0x01,  // AWB disable
		0x3503, 0x13,  // AGC/AEC disable
		0x4005, 0x18,  // [4]: output black line enable
		0x0100, 0x01,  // streaming


};
#endif
//extern void MMPF_Do_Mirror_Flip();
void SNR_OV9726_SetSensorResolution_Customer(ISP_SENSOR_RESOL res)
{
	// implement your change sensor resolution routine here =======================================

	MMP_ULONG VIFGrab_H_Start, VIFGrab_H_Length, VIFGrab_V_Start, VIFGrab_V_Length;

	ISP_IF_AE_SetMinFPSx10(75);
	switch (res) {
	case ISP_SENSOR_RESOL_1280x960:
	case ISP_SENSOR_RESOL_1280x720:

		// set register...........
	/*	for (i = 0; i < VR_ARRSIZE(SNR_OV9726_Reg_1280x720_Customer)/2; i++) {
			gsSensorFunction->MMPF_Sensor_SetReg(SNR_OV9726_Reg_1280x720_Customer[i*2], SNR_OV9726_Reg_1280x720_Customer[i*2+1]);
		}
*/
		// set target fps and corresponding sensor vsync
		ISP_IF_AE_SetSensorVsync(0x0348, 30*10);//bossino fix m2ts AV sync @0928 ISP_IF_SNR_SetFPS(0x0348, 30);

		// set vif grab range which is fetched to ISP (for lens shading and 3A window calculation)
		VIFGrab_H_Start     = 7;
		VIFGrab_H_Length    = 1288;
		VIFGrab_V_Start     = 43;
		VIFGrab_V_Length    = 728;

		ISP_IF_IQ_SetISPInputLength(VIFGrab_H_Length, VIFGrab_V_Length);

		// set scaler downsample rate (for scaler calculation)
		//ISP_IF_SNR_SetDownSample(1, 1);

		// set color id
#if DEFAULT_OV9726_FLIP_FOR_W8_APP
        #if SENSOR_ROTATE_180
		ISP_IF_IQ_SetColorID(1);
        #else
		ISP_IF_IQ_SetColorID(2);// mirror is 1
        #endif		
#else
        #if SENSOR_ROTATE_180
		ISP_IF_IQ_SetColorID(3);
        #else
		ISP_IF_IQ_SetColorID(0);// mirror is 3
        #endif		
#endif

        /*
		// set sensor grab range
		ISP_IF_IQ_SetSensorGrab(	0,					//H_Offest
									0,					//V_Offest
									VIFGrab_H_Length,	//H_Length
									VIFGrab_V_Length,	//V_Length
									1, 1, 				//H_Scale_N, H_Scale_M
									1, 1);				//V_Scale_N, V_Scale_M
		*/
		// calcuate shading ratio
		{
			ISP_UINT32 base_x, base_y;
			ISP_UINT32 x_scale_n = 0x200;
			ISP_UINT32 y_scale_n = 0x200;
			ISP_IF_IQ_GetCaliBase(&base_x, &base_y);
			
			x_scale_n = VIFGrab_H_Length * 0x200 / base_x;
			y_scale_n = VIFGrab_V_Length * 0x200 / base_y;
			
			ISP_IF_IQ_SetCaliRatio(	x_scale_n,	//x_scale_n, 
									0x200,		//x_scale_m, 
									0,			//x_offset, 
									y_scale_n,	//y_scale_n, 
									0x200,		//y_scale_m, 
									0);			//y_offset
		}
		break;
	}
	
	// end of your implementation =================================================================

	// set VIF OPR (Actual sensor output size)
	{
		AITPS_VIF  pVIF = AITC_BASE_VIF;
		volatile MMP_BYTE* pISP = (volatile MMP_BYTE*)AITC_BASE_ISP;
		//MMP_UBYTE   vif_id = 0;

		pVIF->VIF_GRAB[vif_id].PIXL_ST = VIFGrab_H_Start;
		pVIF->VIF_GRAB[vif_id].PIXL_ED = VIFGrab_H_Start + VIFGrab_H_Length -1;
		pVIF->VIF_GRAB[vif_id].LINE_ST = VIFGrab_V_Start ;
		pVIF->VIF_GRAB[vif_id].LINE_ED = VIFGrab_V_Start + VIFGrab_V_Length -1;
		pVIF->VIF_INT_LINE_NUM_0[vif_id] = VIFGrab_V_Length - 61;//121;

#if 1	
		dbg_printf(3,"ViF(xs,xe,ys,ye)=(%d,%d,%d,%d)\r\n",pVIF->VIF_GRAB[vif_id].PIXL_ST,pVIF->VIF_GRAB[vif_id].PIXL_ED,pVIF->VIF_GRAB[vif_id].LINE_ST,pVIF->VIF_GRAB[vif_id].LINE_ED);
        dbg_printf(3, "[0] VIFGrab_H_Length = %d, VIFGrab_V_Length = %d\r\n", VIFGrab_H_Length, VIFGrab_V_Length); 
#endif

		if (m_gsISPCoreID == 868) {
			// ISP pipeline selection
			//APICAL_XBYTE[APICAL_CTL_REG1] &= ~(0x80); // clear auto size
			pISP[0x0B] = 0x30;
			pISP[0x09] = 0x0C;

			// IP ColorID setting
			//pISP[0x09] &= ~(0xF0);
			//pISP[0x09] |= (ISP_IF_SNR_GetColorID() == 0 ? 3 : (ISP_IF_SNR_GetColorID() == 1 ? 2 : (ISP_IF_SNR_GetColorID() == 2 ? 1: 0))) * (0x50);
		}
	}
	//================
	// set iq (NR, Edge, CCM, Gamma, etc.) and functions (saturation, contrast, sharpness, hue, etc.)
	ISP_IF_IQ_SetAll();

	// SetBeforePreview and SetBeforeCapture should be called after getting new configurations of the current resolution
	if (gSystemMode  == VENUS_SYSTEM_MODE_SNAPSHOT) {
		// update AE before capture
		ISP_IF_AE_UpdateBeforeCapture();

		// update AWB before capture
		ISP_IF_AWB_UpdateBeforeCapture();

		// special settings for capture could be set here =============================================
		{
				}
		// end of special settings ====================================================================
	} else if (gSystemMode == VENUS_SYSTEM_MODE_PREVIEW) {
		// update AE before preview
		ISP_IF_AE_UpdateBeforePreview();

		// update AWB before preview
		ISP_IF_AWB_UpdateBeforePreview();
	}

	// set direction (color ID, orientation, etc.)
	ISP_IF_IQ_SetDirection(ISP_IQ_DIRECTION_ORIGINAL);

	// set exposure parameters
	ISP_IF_IQ_SetAEGain(ISP_IF_AE_GetDGain());
	gsSensorFunction->MMPF_Sensor_SetSensorGain(ISP_IF_AE_GetAGain());
	gsSensorFunction->MMPF_Sensor_SetSensorShutter(ISP_IF_AE_GetShutter(), ISP_IF_AE_GetVsync());

	// update ISP window
	ISP_IF_IQ_UpdateInputSize();

	// check if modules are bypassed
	ISP_IF_IQ_CheckBypass();

	// force update iq to hardware
	ISP_IF_IQ_UpdateOprtoHW(ISP_IQ_SWITCH_ALL, 1);
	
}

#if SUPPORT_AUTO_FOCUS
void MOTOR_OV9726_VCM_InitMotor_Customer(void)
{

	//T.B.D
    dbg_printf(3, "###MOTOR_OV9726_VCM_InitMotor_Customer###\r\n");
}


void MOTOR_OV9726_VCM_EnterStandby_Customer(MMP_USHORT af_pos)
{
	//VR_Motor_SmoothMove(af_pos);

}

void MOTOR_OV9726_VCM_SetAFPosition_Customer(MMP_USHORT af_pos)
{

    //dbg_printf(3, "af_pos = %d\r\n", af_pos);
}

MMP_UBYTE MOTOR_OV9726_VCM_CheckAFreachPosition_Customer(MMP_USHORT af_pos)
{
    
    return 1;
    
}
#endif
#if (BIND_SENSOR_OV9726== 1)
MMPF_SENSOR_FUNCTION  *SensorFunction_Module0 = &SensorFunction_OV9726;
#endif

#if (BIND_SENSOR_OV9726== 2)
//MMPF_SENSOR_FUNCTION  *SensorFunction_Module0 = &SensorFunction_dummy;
MMPF_SENSOR_FUNCTION  *SensorFunction_Module1 = &SensorFunction_OV9726;
#endif

#endif  //BIND_SENSOR_OV9726
#endif
